From e1a89757c47d84f64552e2370478da9f2c50dd49 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Mon, 18 Feb 2008 09:33:40 +0000 Subject: [PATCH] amd iommu: Allow device deassignment. Signed-off-by: Wei Wang --- xen/arch/x86/domctl.c | 2 +- xen/arch/x86/hvm/iommu.c | 10 ++++++++++ xen/arch/x86/hvm/svm/amd_iommu/pci-amd-iommu.c | 7 +++++++ xen/arch/x86/hvm/vmx/vtd/intel-iommu.c | 1 + xen/include/asm-x86/iommu.h | 2 ++ 5 files changed, 21 insertions(+), 1 deletion(-) diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c index 3a37b809fd..4e8ad4acde 100644 --- a/xen/arch/x86/domctl.c +++ b/xen/arch/x86/domctl.c @@ -601,7 +601,7 @@ long arch_do_domctl( if ( !device_assigned(bus, devfn) ) break; - reassign_device_ownership(d, dom0, bus, devfn); + deassign_device(d, bus, devfn); gdprintk(XENLOG_INFO, "XEN_DOMCTL_deassign_device: bdf = %x:%x:%x\n", bus, PCI_SLOT(devfn), PCI_FUNC(devfn)); put_domain(d); diff --git a/xen/arch/x86/hvm/iommu.c b/xen/arch/x86/hvm/iommu.c index 30c92f42ea..963ef5a029 100644 --- a/xen/arch/x86/hvm/iommu.c +++ b/xen/arch/x86/hvm/iommu.c @@ -133,3 +133,13 @@ int iommu_unmap_page(struct domain *d, unsigned long gfn) return hd->platform_ops->unmap_page(d, gfn); } + +void deassign_device(struct domain *d, u8 bus, u8 devfn) +{ + struct hvm_iommu *hd = domain_hvm_iommu(d); + + if ( !iommu_enabled || !hd->platform_ops) + return; + + return hd->platform_ops->reassign_device(d, dom0, bus, devfn); +} diff --git a/xen/arch/x86/hvm/svm/amd_iommu/pci-amd-iommu.c b/xen/arch/x86/hvm/svm/amd_iommu/pci-amd-iommu.c index 7caa276f73..815a1aee88 100644 --- a/xen/arch/x86/hvm/svm/amd_iommu/pci-amd-iommu.c +++ b/xen/arch/x86/hvm/svm/amd_iommu/pci-amd-iommu.c @@ -562,10 +562,17 @@ void amd_iommu_domain_destroy(struct domain *d) release_domain_devices(d); } +void amd_iommu_return_device(struct domain *s, struct domain *t, u8 bus, u8 devfn) +{ + pdev_flr(bus, devfn); + reassign_device(s, t, bus, devfn); +} + struct iommu_ops amd_iommu_ops = { .init = amd_iommu_domain_init, .assign_device = amd_iommu_assign_device, .teardown = amd_iommu_domain_destroy, .map_page = amd_iommu_map_page, .unmap_page = amd_iommu_unmap_page, + .reassign_device = amd_iommu_return_device, }; diff --git a/xen/arch/x86/hvm/vmx/vtd/intel-iommu.c b/xen/arch/x86/hvm/vmx/vtd/intel-iommu.c index 79e2e493b6..2eda71514e 100644 --- a/xen/arch/x86/hvm/vmx/vtd/intel-iommu.c +++ b/xen/arch/x86/hvm/vmx/vtd/intel-iommu.c @@ -2164,6 +2164,7 @@ struct iommu_ops intel_iommu_ops = { .teardown = iommu_domain_teardown, .map_page = intel_iommu_map_page, .unmap_page = intel_iommu_unmap_page, + .reassign_device = reassign_device_ownership, }; /* diff --git a/xen/include/asm-x86/iommu.h b/xen/include/asm-x86/iommu.h index 2cea432bbe..1f975dfa53 100644 --- a/xen/include/asm-x86/iommu.h +++ b/xen/include/asm-x86/iommu.h @@ -74,6 +74,7 @@ int iommu_domain_init(struct domain *d); void iommu_domain_destroy(struct domain *d); int device_assigned(u8 bus, u8 devfn); int assign_device(struct domain *d, u8 bus, u8 devfn); +void deassign_device(struct domain *d, u8 bus, u8 devfn); void reassign_device_ownership(struct domain *source, struct domain *target, u8 bus, u8 devfn); @@ -102,6 +103,7 @@ struct iommu_ops { void (*teardown)(struct domain *d); int (*map_page)(struct domain *d, unsigned long gfn, unsigned long mfn); int (*unmap_page)(struct domain *d, unsigned long gfn); + void (*reassign_device)(struct domain *s, struct domain *t, u8 bus, u8 devfn); }; #endif /* _IOMMU_H_ */ -- 2.30.2